package com.yeskery.nut.application.bio;

import com.yeskery.nut.application.NutApplication;
import com.yeskery.nut.application.NutServer;
import com.yeskery.nut.application.NutServerConfigure;
import com.yeskery.nut.core.*;
import com.yeskery.nut.http.bio.BioRequest;
import com.yeskery.nut.http.bio.BioResponse;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 阻塞模式下的 Nut Server 模式，基于传统的 ServerSocket 和 Socket 实现。<b>该类仅用于测试</b>
 * @author sprout
 * @version 1.0
 * 2019-03-18 23:03
 *
 * @deprecated 推荐使用 {@link com.yeskery.nut.application.sun.SunNutServer}
 * 、 {@link com.yeskery.nut.application.jetty.JettyNutServer}、{@link com.yeskery.nut.application.netty.NettyNutServer}。
 */
@Deprecated
public class BioNutServer implements NutServer {

	/** 日志对象 */
	private static final Logger logger = Logger.getLogger(BioNutServer.class.getName());

    /** 是否持续启动服务 */
    private boolean enable = true;

    /** ServerSocket 对象 */
    ServerSocket serverSocket;

    @Override
    public void startServer(NutServerConfigure nutServerConfigure) throws Exception {
        serverSocket = new ServerSocket(nutServerConfigure.getPort());
        logger.info(getServerStartedTip(nutServerConfigure.getPort(), "BIO", false));
		doStartServer(nutServerConfigure.getNutApplication(), nutServerConfigure.getServerContext(),
				nutServerConfigure.getDispatcher(), nutServerConfigure.getSessionManager(),
				nutServerConfigure.getServerRequestConfiguration());
    }

	@Override
    public void close() throws IOException {
        enable = false;
		if (serverSocket != null) {
			serverSocket.close();
		}
	}

	/**
	 * 启动服务的方法
	 * @param nutApplication  Nut应用对象
	 * @param serverContext 服务上下文
	 * @param dispatcher 请求转发器
	 * @param sessionManager session 管理器
	 * @param serverRequestConfiguration 服务请求配置对象
	 * @throws IOException IOException
	 */
    void doStartServer(NutApplication nutApplication, ServerContext serverContext, Dispatcher dispatcher,
					   SessionManager sessionManager, ServerRequestConfiguration serverRequestConfiguration) throws IOException {
		while (enable && !serverSocket.isClosed()) {
			Socket socket = null;
			InputStream inputStream = null;
			OutputStream outputStream = null;
			try {
				socket = serverSocket.accept();
				inputStream = socket.getInputStream();
				outputStream = socket.getOutputStream();
				Request request = new BioRequest(socket, serverContext, sessionManager, serverRequestConfiguration);
				Response response = new BioResponse(nutApplication, outputStream);
				//请求执行的方法
				process(request, response, dispatcher, sessionManager);
			} catch (IOException | NutException e) {
				logger.log(Level.WARNING, "An Error Occurred While Deal Request.", e);
			} finally {
				if (outputStream != null) {
					outputStream.close();
				}
				if (inputStream != null) {
					inputStream.close();
				}
				if (socket != null && !socket.isClosed()) {
					socket.close();
				}
			}
		}
	}
}
